
#include <pic18.h>
#include <delays.h>
#include "macros.h"
#include "sys_clock.h"
#include "uart.h"
#include "app.h"
#include "printf.h"
#include "gpio.h"
#include "atd.h"
#include "dbg.h"

app_t app;

/* ======================================================= */
#define   VIN_VOL_DIV_R1				3300  
#define   VIN_VOL_DIV_R2				510

#define   V_REF				3300000 // uV 
#define   ATD_DIVISION		(V_REF/1024)
#define   mV					1000		//uV
                                            //240768                                        //3222
#define VIN_VOLTS(ROW_DATA) ((((ROW_DATA*(VIN_VOL_DIV_R2+VIN_VOL_DIV_R1))/VIN_VOL_DIV_R2)*ATD_DIVISION)/mV)
/* ======================================================= */

/* near bit phase_A_monitor_finish; */
/* signed long phase_A_start_time, time_from_t0; */
signed long time_from_t0; 
unsigned long vol_raw;
/* unsigned long vol_phase_A; */

#define   GET_TIME_FROM(T0) time_from_t0=TMR1;time_from_t0-=T0;if(time_from_t0<0)time_from_t0+=0xFFFF;		

typedef struct
{
	unsigned int *atd;
	unsigned int amp_voltage;
	unsigned int rms_voltage;
	unsigned int voltage_min;
	unsigned int voltage_max;
	unsigned char debounce_on;		/* in sec */
	unsigned char debounce_off;	/* in sec */
	unsigned char debounce_cnt;
	unsigned char cnt;
	signed long start_time;
	unsigned char state;
	unsigned char status_ok;		  /* input status: if true that the input voltage is OK */
	unsigned char out_num;			  /* relay num */
}input_t;

input_t input_main = {&atd_1_result,0,0,11500,13500,5,5,0,0,0,STATE_WAIT_FOR_ZERO,FALSE,1}; 
input_t input_aux =  {&atd_2_result,0,0,2500,13500,5,5,0,0,0,STATE_WAIT_FOR_ZERO,FALSE,2}; 

void input_monitor ( input_t *input )
{
	//static unsigned char state = STATE_WAIT_FOR_ONE;
	/* dbg("\n\ratd_1_result: %d", atd_1_result); //Dima */
	/* dbg("\n\ratd_2_result: %d", atd_2_result); //Dima */

	if ( SYS_CLOCK(1000) )
	{
		if ( input->status_ok == FALSE )
		{
			if ( input->rms_voltage >= input->voltage_min && input->rms_voltage <= input->voltage_max )
			{
				if ( ++input->debounce_cnt >= input->debounce_on )
				{
					input->status_ok = TRUE;
					input->debounce_cnt = 0;

					if ( input->out_num == 1 )
						pout_out(POUT_RELAY1,1);

					if ( input->out_num == 2 )
						pout_out(POUT_RELAY2,1);
					
				}
			}
			else
			{
				input->debounce_cnt = 0;
			}
		}
		else
		{
			if ( input->rms_voltage < input->voltage_min || input->rms_voltage > input->voltage_max )
			{
				if ( ++input->debounce_cnt >= input->debounce_off )
				{
					input->status_ok = FALSE;
					input->debounce_cnt = 0;
					
					if ( input->out_num == 1 )
						pout_out(POUT_RELAY1,0);

					if ( input->out_num == 2 )
						pout_out(POUT_RELAY2,0);
				}
			}
			else
			{
				input->debounce_cnt = 0;
			}
		}
	}

	switch(input->state)
	{
		/* case STATE_WAIT_FOR_ONE: */
		/* 	if ( *input->atd > 100 ) */
		/* 	{ */
		/* 		if ( ++input->cnt > 10 ) */
		/* 		{ */
		/* 			input->state = STATE_VOLTAGE_MEASUREMENT; */
		/* 			input->cnt = 0; */
		/* 		} */
		/* 	}  */
		/* 	else */
		/* 	{ */
		/* 		input->cnt = 0; */
		/* 		GET_TIME_FROM(input->start_time); */
		/* 		if ( time_from_t0 > 12000 ) */
		/* 		{ */
		/* 			//input->amp_voltage = 0; */
		/* 			input->rms_voltage = 0; */
		/* 			input->state = STATE_WAIT_FOR_ZERO; */
		/* 		} */
		/* 	} */
		/* 	break; */

		case STATE_VOLTAGE_MEASUREMENT:
			GET_TIME_FROM(input->start_time);
			if ( time_from_t0 >= 14500 )
			{
				vol_raw = *input->atd; //atd_1_result;
				input->amp_voltage = VIN_VOLTS(vol_raw);
				vol_raw = input->amp_voltage;
				vol_raw *= 707;
				input->rms_voltage = vol_raw / 1000; 

				input->state = STATE_WAIT_FOR_ZERO;
			}
			break;	

		case STATE_WAIT_FOR_ZERO:
			if ( *input->atd == 0 )
			{
				if ( ++input->cnt > 3 )
				{
					input->start_time = TMR1; /* from this point count the time for shift checking or phase B */
//					dbg("\n\rphase_A_start_time: %u", phase_A_start_time); //Dima
					//input->state = STATE_WAIT_FOR_ONE;
					input->state = STATE_VOLTAGE_MEASUREMENT;
					input->cnt = 0;
					//phase_A_monitor_finish = TRUE;
				}
			} 
			else
			{
				input->cnt = 0;
			}
			break;
	}  
}

//unsigned long vrmsA, vrmsB;

unsigned char app_state_main;

void app_gpn ( void )
{
	input_monitor(&input_main);
	input_monitor(&input_aux);


	if ( SYS_CLOCK(1000) )
	{
		//dbg("\n\rvol input_main: Amp:%lmV(%l); RMS:%lmV;", vol_phase_A, vol_raw, vrmsA); //Dima
		dbg("\n\rvol input_main: Amp:%umV; RMS:%umV; status: %s", input_main.amp_voltage, input_main.rms_voltage,input_main.status_ok?"OK":"FAIL"); //Dima
		dbg("\n\rvol input_aux:  Amp:%umV; RMS:%umV; status: %s", input_aux.amp_voltage, input_aux.rms_voltage,input_aux.status_ok?"OK":"FAIL"); //Dima
	}
}


void app_init ( void )
{
	TRISB3 = 0;
	printf("\n\r SMARTDIN DEVICE: GPN\r\n");
	app = app_gpn;
	//app_state = MAIN_SOURCE_WAIT_FOR_OK;
	/* phase_A_monitor_finish = FALSE; */
	/* phase_B_monitor_finish = FALSE; */
	/* phase_B_shift = 0; */
	//dbg("\nSerial Number: 0x%X",SerNum ); //Dima
//	dbg("\n\rSerial Number: %d",SerNum ); //Dima
}


	/* if ( !SYS_CLOCK(100) ) */
	/* 	return ; */

	/* switch( app_state ) */
	/* { */
	/* 	case MAIN_SOURCE_WAIT_FOR_OK: */
	/* 		if ( input_main.status_ok ) */
	/* 		{ */
	/* 			pout_out(POUT_RELAY1,1); */
	/* 			app_state = MAIN_SOURCE_MONITOR; */
	/* 		} */
	/* 		break; */

	/* 	case MAIN_SOURCE_MONITOR: */
	/* 		if ( input_main.status_ok == FALSE) */
	/* 		{ */
	/* 			pout_out(POUT_RELAY1,0); */
	/* 			app_state = AUX_SOURCE_WAIT_FOR_OK; */
	/* 		} */
	/* 		break; */

	/* 	case AUX_SOURCE_WAIT_FOR_OK: */
	/* 		if ( input_main.status_ok ) */
	/* 		{ */
	/* 			pout_out(POUT_RELAY1,1); */
	/* 			app_state = MAIN_SOURCE_MONITOR; */
	/* 		} */
	/* 		else */
	/* 			if ( input_aux.status_ok ) */
	/* 			{ */
	/* 				pout_out(POUT_RELAY2,1); */
	/* 				app_state = AUX_SOURCE_MONITOR; */
	/* 			}			 */
	/* 		break; */
			
	/* 	case AUX_SOURCE_MONITOR: */
	/* 		if ( input_main.status_ok ) */
	/* 		{ */
	/* 			pout_out(POUT_RELAY2,0); */
	/* 			pout_out(POUT_RELAY1,1); */
	/* 			app_state = MAIN_SOURCE_MONITOR; */
	/* 		} */
	/* 		else */
	/* 			if ( input_aux.status_ok == FALSE) */
	/* 			{ */
	/* 				pout_out(POUT_RELAY2,0); */
	/* 				app_state = MAIN_SOURCE_WAIT_FOR_OK; */
	/* 			} */
	/* 		break; */
	/* }  */




/* void ___input_monitor ( void ) */
/* { */
/* 	static unsigned char state = STATE_WAIT_FOR_ONE, cnt=0; */

/* 	/\* dbg("\n\ratd_1_result: %d", atd_1_result); //Dima *\/ */
/* 	/\* dbg("\n\ratd_2_result: %d", atd_2_result); //Dima *\/ */
	
/* 	switch(state) */
/* 	{ */
/* 		case STATE_WAIT_FOR_ONE: */
/* 			if ( atd_1_result > 100 ) */
/* 			{ */
/* 				if ( ++cnt > 10 ) */
/* 				{ */
/* 					state = STATE_VOLTAGE_MEASUREMENT; */
/* 					cnt = 0; */
/* 				} */
/* 			}  */
/* 			else */
/* 			{ */
/* 				cnt = 0; */
/* 			} */
/* 			break; */

/* 		case STATE_VOLTAGE_MEASUREMENT: */
/* 			GET_TIME_FROM(phase_A_start_time); */
/* 			if ( time_from_t0 >= 14500 ) */
/* 			{ */
/* 				vol_raw = atd_1_result; */
/* 				vol_phase_A = VIN_VOLTS(vol_raw); */

/* 				state = STATE_WAIT_FOR_ZERO; */
/* 			} */
/* 			break;	 */


/* 		case STATE_WAIT_FOR_ZERO: */
/* 			if ( atd_1_result == 0 ) */
/* 			{ */
/* 				if ( ++cnt > 3 ) */
/* 				{ */
/* 					phase_A_start_time = TMR1; /\* from this point count the time for shift checking or phase B *\/ */
/* //					dbg("\n\rphase_A_start_time: %u", phase_A_start_time); //Dima */
/* 					state = STATE_WAIT_FOR_ONE; */
/* 					cnt = 0; */
/* 					phase_A_monitor_finish = TRUE; */
/* 				} */
/* 			}  */
/* 			else */
/* 			{ */
/* 				cnt = 0; */
/* 			} */
/* 			break; */
/* 	}   */
/* } */
